﻿#include "Base64.h"
#include <array>
#include <algorithm>
#include <limits>

namespace base64 {

// 私有常量和辅助函数
namespace {
    // Base64 解码映射表
    constexpr std::array<uint8_t, 80> decode_table = {
        0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
        0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01,
        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
        0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
        0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
        0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
        0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
        0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
    };

    // Base64 编码字符集
    constexpr std::string_view encode_chars = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}

std::optional<std::vector<uint8_t>> decode(std::string_view input) {
    if (input.empty()) {
        return std::vector<uint8_t>{};
    }

    // 预估输出大小（最大可能大小）
    std::vector<uint8_t> output;
    output.reserve(input.size() * 3 / 4 + 1);

    int v = 0;
    int bits = 0;

    for (char c : input) {
        if (c == '=') {
            // 填充字符，跳过
            continue;
        }

        // 计算索引并验证
        unsigned int index = static_cast<unsigned char>(c) - 43;
        if (index >= decode_table.size() || decode_table[index] == 0xff) {
            return std::nullopt; // 无效输入
        }

        // 累积位
        v = (v << 6) + decode_table[index];
        bits += 6;

        // 当累积了足够的位时，提取一个字节
        if (bits >= 8) {
            bits -= 8;
            output.push_back(static_cast<uint8_t>((v >> bits) & 0xFF));
        }
    }

    return output;
}

std::optional<std::string> encode(const std::vector<uint8_t>& input) {
    if (input.empty()) {
        return std::string{};
    }

    // 检查输入大小是否会导致溢出
    if (input.size() >= std::numeric_limits<size_t>::max() / 4) {
        return std::nullopt;
    }

    // 计算输出大小并预分配
    size_t output_size = encoded_size(input.size());
    std::string output;
    output.reserve(output_size);

    size_t i = 0;
    int bits = 0;
    unsigned int value = 0;

    // 处理所有完整的三字节组
    while (i < input.size()) {
        value = (value << 8) | input[i++];
        bits += 8;

        while (bits >= 6) {
            bits -= 6;
            output.push_back(encode_chars[(value >> bits) & 0x3F]);
        }
    }

    // 处理剩余的位
    if (bits > 0) {
        output.push_back(encode_chars[(value << (6 - bits)) & 0x3F]);
    }

    // 添加填充
    while (output.size() % 4 != 0) {
        output.push_back('=');
    }

    return output;
}

std::string encode_string(std::string_view txt) {
    if (txt.empty()) {
        return "";
    }

    // 将字符串转换为字节向量
    std::vector<uint8_t> input(txt.begin(), txt.end());
    
    // 编码并返回
    auto result = encode(input);
    return result.value_or("");
}

std::string decode_string(std::string_view txt) {
    if (txt.empty()) {
        return "";
    }

    // 解码
    auto decoded = decode(txt);
    if (!decoded) {
        return "";
    }

    // 将字节向量转换为字符串
    return std::string(decoded->begin(), decoded->end());
}

} // namespace base64
